applicationwindow: fix leak of help_overlay
authorAlan Jenkins <alan.christopher.jenkins@gmail.com>
Wed, 12 Oct 2016 12:33:39 +0000 (13:33 +0100)
committerMatthias Clasen <mclasen@redhat.com>
Thu, 13 Oct 2016 13:39:01 +0000 (09:39 -0400)
> Due to Gtk+ keeping a reference to the window internally,
> gtk_window_new() does not return a reference to the caller.
> To delete a GtkWindow, call gtk_widget_destroy().

Caller(s) aren't expecting a need to delete help_overlay themselves
once they've installed it.  (E.g. see gtk_application_window_added()).

I didn't notice any direct precedents, but there's a parallel in the
current implementation of gtk_container_destroy() which uses
gtk_widget_destroy() on any added widget.

This avoids leaking 100s of kB per window, when I tested nautilus.

https://bugzilla.gnome.org/show_bug.cgi?id=772859

gtk/gtkapplicationwindow.c

index 2128f983c1bf8a3fb1d8bb7da341e7763553d6e7..3e1e9692b03e6438c47abdbb2a7f6579661fa0c8 100644 (file)
@@ -794,7 +794,12 @@ gtk_application_window_dispose (GObject *object)
 
   g_clear_object (&window->priv->app_menu_section);
   g_clear_object (&window->priv->menubar_section);
-  g_clear_object (&window->priv->help_overlay);
+
+  if (window->priv->help_overlay)
+    {
+      gtk_widget_destroy (GTK_WIDGET (window->priv->help_overlay));
+      g_clear_object (&window->priv->help_overlay);
+    }
 
   G_OBJECT_CLASS (gtk_application_window_parent_class)->dispose (object);
 
@@ -986,6 +991,8 @@ show_help_overlay (GSimpleAction *action,
  * sets up an action with the name win.show-help-overlay to present
  * it.
  *
+ * @window takes resposibility for destroying @help_overlay.
+ *
  * Since: 3.20
  */
 void
@@ -996,8 +1003,7 @@ gtk_application_window_set_help_overlay (GtkApplicationWindow *window,
   g_return_if_fail (help_overlay == NULL || GTK_IS_SHORTCUTS_WINDOW (help_overlay));
 
   if (window->priv->help_overlay)
-    g_signal_handlers_disconnect_by_func (window->priv->help_overlay,
-                                          G_CALLBACK (gtk_widget_hide_on_delete), NULL);
+    gtk_widget_destroy (GTK_WIDGET (window->priv->help_overlay));
   g_set_object (&window->priv->help_overlay, help_overlay);
 
   if (!window->priv->help_overlay)